package objects;

import java.io.PrintWriter;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.TreeMap;

import common.Constants;
import common.GameServer;
import common.LoadingData;
import common.SQLMgr;

public class Character extends Entities {

    private boolean isOnline, isFighting, isSit, isVisible, alignmentStatut;
    private short cellID;
    private int level, pa, pm, race, gfxid, color1, color2, color3, caractPoints, spellPoints,
            vitality, energy, strength, wisdom, agility, luck, intelligence, mapID,alignmentType, 
            alignmentLevel, alignmentGrade, alignmentHonor, alignmentDeshonor, life, po, 
            creatureInvocable, bonusDo, bonusDoP, bonusDoM, bonusDoPer, bonusTrap, bonusTrapPer, 
            bonusHeal, damageReturn, bonusCC, bonusEC, missPa, missPM, resistNeutral, resistNeutralPer, 
            resistEarth, resistEarthPer, resistFire, resistFirePer, resistWater, resistWaterPer, 
            resistAir, resistAirPer, resistPvpNeutral, resistPvpNeutralPer, resistPvpEarth, 
            resistPvpEarthPer, resistPvpFire, resistPvpFirePer, resistPvpWater, resistPvpWaterPer, 
            resistPvpAir, resistPvpAirPer, size, LastEmote;
    private byte sex, isDead, isMerchant, orientation;
    private String name;
    private long guid, kamas, exp, LastSave, QuotaRecruitment, QuotaCommerce;
    private PrintWriter out;
    private Hashtable<String, String> channels = new Hashtable<String, String>();
    private TreeMap<Integer, Item> equipedItems = new TreeMap<Integer, Item>();
    private Hashtable<Integer, Object[]> inventory = new Hashtable<Integer, Object[]>();
    private Hashtable<Long, Spell> spells = new Hashtable<Long, Spell>();
    private Hashtable<Long, Integer> spellsPlaces = new Hashtable<Long, Integer>();
    private Hashtable<Long, Integer> spellsLevel = new Hashtable<Long, Integer>();
    private long fightID;
    
	public Character() {
    }

    public Character(String[] charData, PrintWriter pOut) {
        guid = Long.parseLong(charData[0]);
        name = charData[1];
        sex = Byte.parseByte(charData[3]);
        race = Integer.parseInt(charData[4]);
        gfxid = Integer.parseInt(charData[5]);
        color1 = Integer.parseInt(charData[6]);
        color2 = Integer.parseInt(charData[7]);
        color3 = Integer.parseInt(charData[8]);
        level = Integer.parseInt(charData[9]);
        isDead = Byte.parseByte(charData[10]);
        isMerchant = Byte.parseByte(charData[11]);
        //inventory.put(0, charData[12]); //FIXME : parse item to create it into the inventory
        exp = Long.parseLong((charData[13]));
        kamas = Long.parseLong((charData[14]));
        caractPoints = Integer.parseInt(charData[15]);
        spellPoints = Integer.parseInt(charData[16]);
        vitality = Integer.parseInt(charData[17]);
        energy = Integer.parseInt(charData[18]);
        strength = Integer.parseInt(charData[19]);
        wisdom = Integer.parseInt(charData[20]);
        agility = Integer.parseInt(charData[21]);
        luck = Integer.parseInt(charData[22]);
        intelligence = Integer.parseInt(charData[23]);
        mapID = Integer.parseInt(charData[24]);
        cellID = Short.parseShort(charData[25]);
        setSpells(charData[26]);
        pa = Integer.parseInt(charData[27]);
        pm = Integer.parseInt(charData[28]);
        alignmentType = Integer.parseInt(charData[29]);
        alignmentLevel = Integer.parseInt(charData[30]);
        alignmentGrade = Integer.parseInt(charData[31]);
        alignmentHonor = Integer.parseInt(charData[32]);
        alignmentDeshonor = Integer.parseInt(charData[33]);
        alignmentStatut = Boolean.parseBoolean(charData[34]);
        life = Integer.parseInt(charData[35]);
        po = Integer.parseInt(charData[36]);
        creatureInvocable = Integer.parseInt(charData[37]);
        bonusDo = Integer.parseInt(charData[38]);
        bonusDoP = Integer.parseInt(charData[39]);
        bonusDoM = Integer.parseInt(charData[40]);
        bonusDoPer = Integer.parseInt(charData[41]);
        bonusTrap = Integer.parseInt(charData[42]);
        bonusTrapPer = Integer.parseInt(charData[43]);
        bonusHeal = Integer.parseInt(charData[44]);
        damageReturn = Integer.parseInt(charData[45]);
        bonusCC = Integer.parseInt(charData[46]);
        bonusEC = Integer.parseInt(charData[47]);
        missPa = Integer.parseInt(charData[48]);
        missPM = Integer.parseInt(charData[49]);
        resistNeutral = Integer.parseInt(charData[50]);
        resistNeutralPer = Integer.parseInt(charData[51]);
        resistEarth = Integer.parseInt(charData[52]);
        resistEarthPer = Integer.parseInt(charData[53]);
        resistFire = Integer.parseInt(charData[54]);
        resistFirePer = Integer.parseInt(charData[55]);
        resistWater = Integer.parseInt(charData[56]);
        resistWaterPer = Integer.parseInt(charData[57]);
        resistAir = Integer.parseInt(charData[58]);
        resistAirPer = Integer.parseInt(charData[59]);
        resistPvpNeutral = Integer.parseInt(charData[60]);
        resistPvpNeutralPer = Integer.parseInt(charData[61]);
        resistPvpEarth = Integer.parseInt(charData[62]);
        resistPvpEarthPer = Integer.parseInt(charData[63]);
        resistPvpFire = Integer.parseInt(charData[64]);
        resistPvpFirePer = Integer.parseInt(charData[65]);
        resistPvpWater = Integer.parseInt(charData[66]);
        resistPvpWaterPer = Integer.parseInt(charData[67]);
        resistPvpAir = Integer.parseInt(charData[68]);
        resistPvpAirPer = Integer.parseInt(charData[69]);
        this.setEquipedItems(charData[71]);
        //equipedItems.put(key, value) FIXME : Create a parser to add equiped items to the character
        size = Integer.parseInt(charData[72]);
        isOnline = false;
        isFighting = false;
        fightID = 0;
        //charData[70];

        out = pOut;
    }

    @Override
	public long getEntitieMapGuid() {
		return guid;
	}

	@Override
	public String getGmPacket() {
		return "";
	}

	@Override
	public byte getOrientation() {
		return orientation;
	}

	@Override
	public boolean isVisible() {
		return isVisible;
	}

	@Override
	public byte getEntitieType() {
		return Constants.MAP_ENTITIE_TYPE_CHARACTER;
	}

	@Override
	public void setEntitieMapGuid(long pGuid) {
		this.guid = pGuid;
	}

	@Override
	public void setVisible(boolean v) {
		this.isVisible = v;
	}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public int getRace() {
        return race;
    }

    public void setRace(int race) {
        this.race = race;
    }

    public byte getSex() {
        return sex;
    }

    public void setSex(byte sex) {
        this.sex = sex;
    }

    public int getGfxid() {
        return gfxid;
    }

    public void setGfxid(int gfxid) {
        this.gfxid = gfxid;
    }

    public int getColor1() {
        return color1;
    }

    public void setColor1(int color1) {
        this.color1 = color1;
    }

    public int getColor2() {
        return color2;
    }

    public void setColor2(int color2) {
        this.color2 = color2;
    }

    public int getColor3() {
        return color3;
    }

    public void setColor3(int color3) {
        this.color3 = color3;
    }

    public Hashtable<Integer, Object[]> getInventory() {
        return inventory;
    }

    public void addToInventory(Item item, int quantity) {
        this.inventory.remove(item.getGuid());

        Object[] oItem = {};

        oItem[0] = item;
        oItem[1] = quantity;

        if (oItem != null) {
            this.inventory.put(item.getGuid(), oItem);
        }
    }

    public long getKamas() {
        return kamas;
    }

    public void setKamas(long kamas) {
        this.kamas = kamas;
    }

    public long getExp() {
        return exp;
    }

    public void setExp(long exp) {
        this.exp = exp;
    }

    public int getCaractPoints() {
        return caractPoints;
    }

    public void setCaractPoints(int caractPoints) {
        this.caractPoints = caractPoints;
    }

    public int getSpellPoints() {
        return spellPoints;
    }

    public void setSpellPoints(int spellPoints) {
        this.spellPoints = spellPoints;
    }

    public int getVitality() {
        return vitality;
    }

    public void setVitality(int vitality) {
        this.vitality = vitality;
    }

    public int getEnergy() {
        return energy;
    }

    public void setEnergy(int energy) {
        this.energy = energy;
    }

    public int getStrength() {
        return strength;
    }

    public void setStrength(int strength) {
        this.strength = strength;
    }

    public int getWisdom() {
        return wisdom;
    }

    public void setWisdom(int widsom) {
        this.wisdom = widsom;
    }

    public int getAgility() {
        return agility;
    }

    public void setAgility(int agility) {
        this.agility = agility;
    }

    public int getLuck() {
        return luck;
    }

    public void setLuck(int luck) {
        this.luck = luck;
    }

    public int getIntelligence() {
        return intelligence;
    }

    public void setIntelligence(int intelligence) {
        this.intelligence = intelligence;
    }

    public int getMapID() {
        return mapID;
    }

    public void setMapID(int mapID) {
        this.mapID = mapID;
    }

    public short getCellID() {
        return cellID;
    }

    public void setCellID(short cellID) {
        this.cellID = cellID;
    }

    public void addSpell(Spell pSpell) {
        this.spells.put(pSpell.getGuid(), pSpell);
    }

    public int getPa() {
        return pa;
    }

    public void setPa(int pa) {
        this.pa = pa;
    }

    public int getPm() {
        return pm;
    }

    public void setPm(int pm) {
        this.pm = pm;
    }

    public byte isDead() {
        return isDead;
    }

    public void setDead(byte isDead) {
        this.isDead = isDead;
    }

    public byte isMerchant() {
        return isMerchant;
    }

    public void setMerchant(byte isMerchant) {
        this.isMerchant = isMerchant;
    }

    public boolean getAlignmentStatut() {
        return alignmentStatut;
    }

    public void setAlignmentStatut(boolean alignmentStatut) {
        this.alignmentStatut = alignmentStatut;
    }

    public int getAlignmentType() {
        return alignmentType;
    }

    public void setAlignmentType(int alignmentType) {
        this.alignmentType = alignmentType;
    }

    public int getAlignmentLevel() {
        return alignmentLevel;
    }

    public void setAlignmentLevel(int alignmentLevel) {
        this.alignmentLevel = alignmentLevel;
    }

    public int getAlignmentGrade() {
        return alignmentGrade;
    }

    public void setAlignmentGrade(int alignmentGrade) {
        this.alignmentGrade = alignmentGrade;
    }

    public int getAlignmentHonor() {
        return alignmentHonor;
    }

    public void setAlignmentHonor(int alignmentHonor) {
        this.alignmentHonor = alignmentHonor;
    }

    public int getAlignmentDeshonor() {
        return alignmentDeshonor;
    }

    public void setAlignmentDeshonor(int alignmentDeshonor) {
        this.alignmentDeshonor = alignmentDeshonor;
    }

    public int getPdvMax(int pLevel, int pBasePdv) {
        return ((pLevel - 1) * 5) + pBasePdv; // TODO Stuff bonus
    }

    public void setLife(int life) {
        this.life = life;
    }

    public int getLife() {
        return life;
    }

    public int getPo() {
        return po;
    }

    public void setPo(int po) {
        this.po = po;
    }

    public int getCreatureInvocable() {
        return creatureInvocable;
    }

    public void setCreatureInvocable(int creatureInvocable) {
        this.creatureInvocable = creatureInvocable;
    }

    public int getBonusDo() {
        return bonusDo;
    }

    public void setBonusDo(int bonusDo) {
        this.bonusDo = bonusDo;
    }

    public int getBonusDoP() {
        return bonusDoP;
    }

    public void setBonusDoP(int bonusDoP) {
        this.bonusDoP = bonusDoP;
    }

    public int getBonusDoM() {
        return bonusDoM;
    }

    public void setBonusDoM(int bonusDoM) {
        this.bonusDoM = bonusDoM;
    }

    public int getBonusDoPer() {
        return bonusDoPer;
    }

    public void setBonusDoPer(int bonusDoPer) {
        this.bonusDoPer = bonusDoPer;
    }

    public int getBonusTrap() {
        return bonusTrap;
    }

    public void setBonusTrap(int bonusTrap) {
        this.bonusTrap = bonusTrap;
    }

    public int getBonusTrapPer() {
        return bonusTrapPer;
    }

    public void setBonusTrapPer(int bonusTrapPer) {
        this.bonusTrapPer = bonusTrapPer;
    }

    public int getBonusHeal() {
        return bonusHeal;
    }

    public void setBonusHeal(int bonusHeal) {
        this.bonusHeal = bonusHeal;
    }

    public int getDamageReturn() {
        return damageReturn;
    }

    public void setDamageReturn(int damageReturn) {
        this.damageReturn = damageReturn;
    }

    public int getBonusCC() {
        return bonusCC;
    }

    public void setBonusCC(int bonusCC) {
        this.bonusCC = bonusCC;
    }

    public int getBonusEC() {
        return bonusEC;
    }

    public void setBonusEC(int bonusEC) {
        this.bonusEC = bonusEC;
    }

    public int getMissPa() {
        return missPa;
    }

    public void setMissPa(int missPa) {
        this.missPa = missPa;
    }

    public int getMissPM() {
        return missPM;
    }

    public void setMissPM(int missPM) {
        this.missPM = missPM;
    }

    public int getResistNeutral() {
        return resistNeutral;
    }

    public void setResistNeutral(int resistNeutral) {
        this.resistNeutral = resistNeutral;
    }

    public int getResistNeutralPer() {
        return resistNeutralPer;
    }

    public void setResistNeutralPer(int resistNeutralPer) {
        this.resistNeutralPer = resistNeutralPer;
    }

    public int getResistEarth() {
        return resistEarth;
    }

    public void setResistEarth(int resistEarth) {
        this.resistEarth = resistEarth;
    }

    public int getResistEarthPer() {
        return resistEarthPer;
    }

    public void setResistEarthPer(int resistEarthPer) {
        this.resistEarthPer = resistEarthPer;
    }

    public int getResistFire() {
        return resistFire;
    }

    public void setResistFire(int resistFire) {
        this.resistFire = resistFire;
    }

    public int getResistFirePer() {
        return resistFirePer;
    }

    public void setResistFirePer(int resistFirePer) {
        this.resistFirePer = resistFirePer;
    }

    public int getResistWater() {
        return resistWater;
    }

    public void setResistWater(int resistWater) {
        this.resistWater = resistWater;
    }

    public int getResistWaterPer() {
        return resistWaterPer;
    }

    public void setResistWaterPer(int resistWaterPer) {
        this.resistWaterPer = resistWaterPer;
    }

    public int getResistAir() {
        return resistAir;
    }

    public void setResistAir(int resistAir) {
        this.resistAir = resistAir;
    }

    public int getResistAirPer() {
        return resistAirPer;
    }

    public void setResistAirPer(int resistAirPer) {
        this.resistAirPer = resistAirPer;
    }

    public int getResistPvpNeutral() {
        return resistPvpNeutral;
    }

    public void setResistPvpNeutral(int resistPvpNeutral) {
        this.resistPvpNeutral = resistPvpNeutral;
    }

    public int getResistPvpNeutralPer() {
        return resistPvpNeutralPer;
    }

    public void setResistPvpNeutralPer(int resistPvpNeutralPer) {
        this.resistPvpNeutralPer = resistPvpNeutralPer;
    }

    public int getResistPvpEarth() {
        return resistPvpEarth;
    }

    public void setResistPvpEarth(int resistPvpEarth) {
        this.resistPvpEarth = resistPvpEarth;
    }

    public int getResistPvpEarthPer() {
        return resistPvpEarthPer;
    }

    public void setResistPvpEarthPer(int resistPvpEarthPer) {
        this.resistPvpEarthPer = resistPvpEarthPer;
    }

    public int getResistPvpFire() {
        return resistPvpFire;
    }

    public void setResistPvpFire(int resistPvpFire) {
        this.resistPvpFire = resistPvpFire;
    }

    public int getResistPvpFirePer() {
        return resistPvpFirePer;
    }

    public void setResistPvpFirePer(int resistPvpFirePer) {
        this.resistPvpFirePer = resistPvpFirePer;
    }

    public int getResistPvpWater() {
        return resistPvpWater;
    }

    public void setResistPvpWater(int resistPvpWater) {
        this.resistPvpWater = resistPvpWater;
    }

    public int getResistPvpWaterPer() {
        return resistPvpWaterPer;
    }

    public void setResistPvpWaterPer(int resistPvpWaterPer) {
        this.resistPvpWaterPer = resistPvpWaterPer;
    }

    public int getResistPvpAir() {
        return resistPvpAir;
    }

    public void setResistPvpAir(int resistPvpAir) {
        this.resistPvpAir = resistPvpAir;
    }

    public int getResistPvpAirPer() {
        return resistPvpAirPer;
    }

    public void setResistPvpAirPer(int resistPvpAirPer) {
        this.resistPvpAirPer = resistPvpAirPer;
    }

    public boolean isOnline() {
        return isOnline;
    }

    public void setOnline(boolean isOnline) {
        this.isOnline = isOnline;
    }

    public boolean isFighting() {
        return isFighting;
    }

    public void setFighting(boolean isFighting) {
        this.isFighting = isFighting;
    }

    public Hashtable<String, String> getChannels() {
        return this.channels;
    }

    public void setChannels(String chan, String action) {
        this.channels.remove(chan);
        this.channels.put(chan, action);
    }

    public PrintWriter getOut() {
        return out;
    }

    public void setOut(PrintWriter out) {
        this.out = out;
    }

    public void deleteFromMap() {
        Map mapDatas = LoadingData.getMapData().get(mapID);

        mapDatas.getCharacterOnMap().remove(guid);
    }

    public TreeMap<Integer, Item> getEquipedItems() {
        return equipedItems;
    }

    public void equipItem(Item item, int slot) {
        equipedItems.remove(slot);
        equipedItems.put(slot, item);
    }

    public void setEquipedItems(String pItems) {
        if (pItems != null && !pItems.isEmpty()) {
            String[] items = pItems.split("\\|");
            String[] splittedItems;
            int i = 0;

            for (String item : items) {
                i++;
                splittedItems = item.split(",");

                // First is item id
                // rest is effects

                // Clone the original item
                Item clonedItem = LoadingData.getItemData().get(Integer.parseInt(splittedItems[0]));

                // Change effects
                clonedItem.getEffects().clear(); // Clear all effects

                for (int effectN = 1; effectN > splittedItems.length; i++) {
                    clonedItem.addEffects(splittedItems[effectN]);
                }

                equipItem(clonedItem, i);
            }
        }
    }

    public void setInventory(String pItems) {
        if (pItems != null) {
            Object[] oItem = {null, 0};
            String[] items = pItems.split("\\|");
            String[] splittedItems;
            int i = 0;

            for (String item : items) {
                i++;
                splittedItems = item.split(","); // id,quantity,slot,effects

                // Clone the original item
                Item clonedItem = LoadingData.getItemData().get(Integer.parseInt(splittedItems[0]));
                GameServer.writeLine("Size " + splittedItems.length);
                if (splittedItems.length > 3) // Items with effects
                {
                    clonedItem.getEffects().clear(); // Clear all effects
                    clonedItem.setSlot(Integer.parseInt(splittedItems[2]));

                    for (int effectN = 3; effectN < splittedItems.length; effectN++) {
                        clonedItem.addEffects(splittedItems[effectN]);
                        GameServer.writeLine("Add effect " + splittedItems[effectN] + " to item " + splittedItems[0]);
                    }
                } else // Simple item
                {
                }

                if (clonedItem != null) {
                    oItem[0] = clonedItem;
                    oItem[1] = Integer.parseInt(splittedItems[1]);
                    inventory.put(clonedItem.getGuid(), oItem.clone());
                }
            }
        }
    }

    public static String getEquipedItems(String pItems) {
        if (pItems == null || pItems.isEmpty()) {
            return "";
        }
        String[] items = pItems.split("\\|");
        String[] splittedItems;
        String formatedEquipedItems = "";

        for (int i = 0; i < items.length; i++) {
            GameServer.writeLine("Item : " + items[i]);
            splittedItems = items[i].split(",");

            formatedEquipedItems += Integer.toHexString(Integer.parseInt(splittedItems[0]));
            formatedEquipedItems += (i + 1 < items.length) ? "," : "";
        }

        return formatedEquipedItems;
    }

    public TreeMap<Integer, Item> getEquipedItem() {
        return equipedItems;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public long getLastSave() {
        return LastSave;
    }

    public void setLastSave(long LastSave) {
        this.LastSave = LastSave;
    }

    public long getLastEmote() {
        return LastEmote;
    }

    public void setLastEmote(int LastEmote) {
        if (LastEmote == 1) {
            this.setIsSit(true);            
        }
        else {
            this.setIsSit(false);
        }
        this.LastEmote = LastEmote;
    }

    public Item addItem(int itemID, int quantity) {
        Item item = LoadingData.getItemData().get(itemID);
        Object[] oItem = {};

        if (item != null) {
            oItem[0] = item;
            oItem[1] = quantity;
            inventory.put(itemID, oItem);

            return item;
        } else {
            return null;
        }
    }
    
    private void setSpells(String pSpellDatas)
    {
    	String[] splittedDatas = pSpellDatas.split("\\|");
    	
    	for(int i = 0; i < (splittedDatas.length);i++)
    	{
    		GameServer.writeLine("splittedDatas[i] = " + splittedDatas[i]);
    		String[] subDatas = splittedDatas[i].split(";");
    		
    		Spell newSpell = LoadingData.getSpellData().get(Long.parseLong(subDatas[0]));
    		
    		if(newSpell != null)
    		{
    			GameServer.writeLine("Add new spell " + newSpell.getName() + " level " + subDatas[1] + " at place " + subDatas[2]);
    			this.spells.put(newSpell.getGuid(), newSpell); // Add spell at spells list
    			this.spellsPlaces.put(Long.parseLong(subDatas[0]), Integer.parseInt(subDatas[2]));
    			this.spellsLevel.put(newSpell.getGuid(), Integer.parseInt(subDatas[1]));
    		}
    	}
    }
    
    public String getSpellList()
    {
    	String list = "";
    	
    	Iterator<Spell> spellsIter = spells.values().iterator();
    	Iterator<Integer> spellsLevelIter = spellsLevel.values().iterator();
    	Iterator<Integer> spellsPlacesIter = spellsPlaces.values().iterator();
    	
    	while(spellsIter.hasNext() && spellsLevelIter.hasNext() && spellsPlacesIter.hasNext())
    	{
    		list += spellsIter.next().getGuid() + "~";
    		list += spellsLevelIter.next() + "~";
    		list += spellsPlacesIter.next();
    		
    		list += (spellsIter.hasNext() && spellsLevelIter.hasNext() && spellsPlacesIter.hasNext()) ? "|" : "";
    	}
    	
    	return list;
    }

    public String getInventoryToSave() {
        String inventorySave = "";

        Iterator<Object[]> vIter = inventory.values().iterator();

        while (vIter.hasNext()) {
            Object[] value = vIter.next();

            inventorySave += ((Item) value[0]).getGuid() + ","; // itemID
            inventorySave += value[1] + ","; // quantity
            inventorySave += ((Item) value[0]).getSlot() + ","; // Slot
            inventorySave += getEffectsToSave(((Item) value[0]).getEffects()); // effects
            inventorySave += (vIter.hasNext()) ? "|" : "";
        }

        return inventorySave;
    }

    public String getEffectsToSave(Hashtable<Integer, String> effects) {
        String effectsSave = "";

        Iterator<String> vIter = effects.values().iterator();

        while (vIter.hasNext()) {
            String value = vIter.next();

            effectsSave += value;
            effectsSave += (vIter.hasNext()) ? "," : "";
        }

        return effectsSave;
    }

    public String getEquippedItemsToSave() {
        String equippedSave = "";

        Iterator<Item> vIter = equipedItems.values().iterator();

        while (vIter.hasNext()) {
            Item value = vIter.next();

            equippedSave += value.getGuid(); // ItemID
            equippedSave += getEffectsToSave(value.getEffects());
            equippedSave += (vIter.hasNext()) ? "|" : "";
        }

        return equippedSave;
    }
    
    public String getSpellsToSave()
    {
    	String spellsToSave = "";
    	
    	Iterator<Spell> vIter = spells.values().iterator();
    	
    	while(vIter.hasNext())
    	{
    		Spell spellSave = vIter.next();
    		
    		spellsToSave += spellSave.getGuid() + ";" + getSpellsLevel().get(spellSave.getGuid()) + ";" + getSpellsPlaces().get(spellSave.getGuid());
    		spellsToSave += (vIter.hasNext()) ? "|" : "";
    	}
    	
    	return spellsToSave;
    }

    public synchronized void saveChar() {
        Statement stat = SQLMgr.createStat();
        if (SQLMgr.getSelfSQL() == null) {
            GameServer.writeLine("SQL Error : Self = null");
        }
        //SQLMgr.queryU(stat, "UPDATE `characters` SET `gfxid`='"+ getGfxid() +"', `level`='"+ getLevel() +"', `isDead`='"+ isDead() +"', `isMerchant`='"+ isMerchant() +"', `items`='"+ /*getEquipedItem() +*/"', `inventory`='"/*+ getInventory() +*/ +"', `exp`='"+ getExp() +"', `kamas`='"+ getKamas() +"', `caractPoints`='"+ getCaractPoints() +"', `spellsPoints`='"+ getSpellPoints() +"', `vitality`='"+ getLife() +"', `energy`='"+ getEnergy() +"', `strength`='"+ getStrength() +"', `wisdom`='"+ getWisdom() +"', `agility`='"+ getAgility() +"', `luck`='"+ getLuck() +"', `intelligence`='"+ getIntelligence() +"', `mapID`='"+ getMapID() +"', `cellID`='"+ getCellID() +"', `spells`='"+ getSpells() +"', `pa`='"+ getPa() +"', `pm`='"+ getPm() +"', `alignment`='"+ getAlignmentType() +"', `aLevel`='"+ getAlignmentLevel() +"', `aGrade`='"+ getAlignmentLevel() +"', `aHonor`='"+ getAlignmentHonor() +"', `aDeshonor`='"+ getAlignmentDeshonor() +"', `aStatut`='"+ getAlignmentStatut() +"', `life`='"+ getLife() +"', `po`='"+ getPo() +"', `CreatureInvocable`='"+ getCreatureInvocable() +"', `bonusDo`='"+ getBonusDo() +"', `bonusDoP`='"+ getBonusDoP() +"', `bonusDoM`='"+ getBonusDoM() +"', `bonusDoPer`='"+ getBonusDoPer() +"', `bonusTrap`='"+ getBonusTrap() +"', `bonusTrapPer`='"+ getBonusTrapPer() +"', `bonusHeal`='"+ getBonusHeal() +"', `damageReturn`='"+ getDamageReturn() +"', `bonusCC`='"+ getBonusCC() +"', `bonusEC`='"+ getBonusEC() +"', `missPa`='"+ getMissPa() +"', `missPM`='"+ getMissPM() +"', `resistNeutral`='"+ getResistNeutral() +"', `resistNeutralPer`='"+ getResistNeutralPer() +"', `resistEarth`='"+ getResistEarth() +"', `resistEarthPer`='"+ getResistEarthPer() +"', `resistFire`='"+ getResistFire() +"', `resistFirePer`='"+ getResistFirePer() +"', `resistWater`='"+ getResistWater() +"', `resistWaterPer`='"+ getResistWaterPer() +"', `resistAir`='"+ getResistAir() +"', `resistAirPer`='"+ getResistAirPer() +"', `resistPvpNeutral`='"+ getResistPvpNeutral() +"', `resistPvpNeutralPer`='"+ getResistPvpNeutralPer() +"', `resistPvpEarth`='"+ getResistPvpEarth() +"', `resistPvpEarthPer`='"+ getResistPvpEarthPer() +"', `resistPvpFire`='"+ getResistPvpFire() +"', `resistPvpFirePer`='"+ getResistPvpFirePer() +"', `resistPvpWater`='"+ getResistPvpWater() +"', `resistPvpWaterPer`='"+ getResistPvpWaterPer() +"', `resistPvpAir`='"+ getResistPvpAir() +"', `resistPvpAirPer`='"+ getResistPvpAirPer() +"', `isOnline`='"+ (isOnline()?1:0) +"', `channels`='"+ /*getChannels() +*/"', `size`='"+ getSize() +"' WHERE (`pseudo`='"+ getName() +"')");
        SQLMgr.queryU(stat, "UPDATE `characters` SET `gfxid`='" + getGfxid() + "', `level`='" + getLevel() + "', `isDead`='" + isDead() + "', `isMerchant`='" + isMerchant() + "', `exp`='" + getExp() + "', `kamas`='" + getKamas() + "', `caractPoints`='" + getCaractPoints() + "', `spellsPoints`='" + getSpellPoints() + "', `vitality`='" + getVitality() + "', `energy`='" + getEnergy() + "', `strength`='" + getStrength() + "', `wisdom`='" + getWisdom() + "', `agility`='" + getAgility() + "', `luck`='" + getLuck() + "', `intelligence`='" + getIntelligence() + "', `mapID`='" + getMapID() + "', `cellID`='" + getCellID() + "', `spells`='" + getSpellsToSave() + "', `pa`='" + getPa() + "', `pm`='" + getPm() + "', `alignment`='" + getAlignmentType() + "', `aLevel`='" + getAlignmentLevel() + "', `aGrade`='" + getAlignmentLevel() + "', `aHonor`='" + getAlignmentHonor() + "', `aDeshonor`='" + getAlignmentDeshonor() + "', `aStatut`='" + (getAlignmentStatut() ? "1" : "0") + "', `life`='" + getLife() + "', `po`='" + getPo() + "', `CreatureInvocable`='" + getCreatureInvocable() + "', `bonusDo`='" + getBonusDo() + "', `bonusDoP`='" + getBonusDoP() + "', `bonusDoM`='" + getBonusDoM() + "', `bonusDoPer`='" + getBonusDoPer() + "', `bonusTrap`='" + getBonusTrap() + "', `bonusTrapPer`='" + getBonusTrapPer() + "', `bonusHeal`='" + getBonusHeal() + "', `damageReturn`='" + getDamageReturn() + "', `bonusCC`='" + getBonusCC() + "', `bonusEC`='" + getBonusEC() + "', `missPa`='" + getMissPa() + "', `missPM`='" + getMissPM() + "', `resistNeutral`='" + getResistNeutral() + "', `resistNeutralPer`='" + getResistNeutralPer() + "', `resistEarth`='" + getResistEarth() + "', `resistEarthPer`='" + getResistEarthPer() + "', `resistFire`='" + getResistFire() + "', `resistFirePer`='" + getResistFirePer() + "', `resistWater`='" + getResistWater() + "', `resistWaterPer`='" + getResistWaterPer() + "', `resistAir`='" + getResistAir() + "', `resistAirPer`='" + getResistAirPer() + "', `resistPvpNeutral`='" + getResistPvpNeutral() + "', `resistPvpNeutralPer`='" + getResistPvpNeutralPer() + "', `resistPvpEarth`='" + getResistPvpEarth() + "', `resistPvpEarthPer`='" + getResistPvpEarthPer() + "', `resistPvpFire`='" + getResistPvpFire() + "', `resistPvpFirePer`='" + getResistPvpFirePer() + "', `resistPvpWater`='" + getResistPvpWater() + "', `resistPvpWaterPer`='" + getResistPvpWaterPer() + "', `resistPvpAir`='" + getResistPvpAir() + "', `resistPvpAirPer`='" + getResistPvpAirPer() + "', `isOnline`='" + (isOnline() ? 1 : 0) + "', `size`='" + getSize() + "' WHERE (`pseudo`='" + getName() + "')");
        SQLMgr.freeSQLStat(stat);
        GameServer.writeLine("Personnage " + getName() + " sauvegardé");
    }

    public final long getTimeRecruitment() {
        return (QuotaRecruitment - System.currentTimeMillis()) / 1000;
    }

    public final boolean getCanRecruitment() {
        return getTimeRecruitment() <= 0;
    }

    public final void SetRecruitment() {
        QuotaRecruitment = System.currentTimeMillis() + 30 * 1000;
    }

    public final long getTimeCommerce() {
        return (QuotaCommerce - System.currentTimeMillis()) / 1000;
    }

    public final boolean getCanCommerce() {
        return getTimeCommerce() <= 0;
    }

    public final void SetCommerce() {
        QuotaCommerce = System.currentTimeMillis() + 30 * 1000;
    }

    public boolean isIsSit() {
        return isSit;
    }

    public void setIsSit(boolean isSit) {
        this.isSit = isSit;
    }
    
    public long getFightID() {
		return fightID;
	}

	public void setFightID(long fightID) {
		this.fightID = fightID;
	}

	public Hashtable<Long, Integer> getSpellsPlaces()
	{
		return spellsPlaces;
	}
	
	public void addSpellsPlaces(long spellID, int place)
	{
		this.spellsPlaces.put(spellID, place);
	}
	
	public Hashtable<Long, Integer> getSpellsLevel()
	{
		return spellsLevel;
	}
	
	public void addSpellsLevel(long spellID, int level)
	{
		this.spellsPlaces.put(spellID, level);
	}
	
}